package com.hup.sokoban.service.mapDesigner;

import com.hup.sokoban.constant.MapConstant.ElementType;
import com.hup.sokoban.model.common.MapItem;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

/**
 * 处理地图边界和移动的逻辑类
 * @author hugan
 * @date 2020/5/6
 */
@Log4j2
@Component
public class MapBoundsService {

    public boolean moveUp(MapItem mapItem) {
        int[] map = mapItem.getMap();
        int width = mapItem.getWidth();

        for (int i = 0; i < width; i++) {
            if (map[i] != ElementType.EMPTY.intValue) {
                return false;
            }
        }
        int[] temp = map;
        map = new int[map.length];
        System.arraycopy(temp, width, map, 0, temp.length - width);
        mapItem.setMap(map);
        return true;
    }

    public boolean moveDown(MapItem mapItem) {
        int[] map = mapItem.getMap();
        int width = mapItem.getWidth();

        for (int i = map.length - width; i < map.length; i++) {
            if (map[i] != ElementType.EMPTY.intValue) {
                return false;
            }
        }
        int[] temp = map;
        map = new int[map.length];
        System.arraycopy(temp, 0, map, width, temp.length - width);
        mapItem.setMap(map);
        return true;
    }

    public boolean moveLeft(MapItem mapItem) {
        int[] map = mapItem.getMap();
        int width = mapItem.getWidth();
        int height = mapItem.getHeight();

        log.debug("w={}, h={}, l={}", width, height, map.length);
        for (int i = 0; i < map.length; i += width) {
            log.debug("i={}", i);
            if (map[i] != ElementType.EMPTY.intValue) {
                return false;
            }
        }
        for (int row = 0; row < height; row++) {
            for (int col = 0; col < width; col++) {
                int i = row * width + col;
                if (col < width - 1) {
                    map[i] = map[i + 1];
                } else {
                    map[i] = ElementType.EMPTY.intValue;
                }
            }
        }
        return true;
    }

    public boolean moveRight(MapItem mapItem) {
        int[] map = mapItem.getMap();
        int width = mapItem.getWidth();
        int height = mapItem.getHeight();

        log.debug("w={}, h={}, l={}", width, height, map.length);
        for (int i = width - 1; i < map.length; i += width) {
            log.debug("i={}", i);
            if (map[i] != ElementType.EMPTY.intValue) {
                return false;
            }
        }
        for (int row = 0; row < height; row++) {
            for (int col = width - 1; col >= 0; col--) {
                int i = row * width + col;
                if (col == 0) {
                    map[i] = ElementType.EMPTY.intValue;
                } else {
                    map[i] = map[i - 1];
                }
            }
        }
        return true;
    }

    /**
     * 添加最后一行
     */
    public boolean rowAdd(MapItem mapItem) {
        int[] map = mapItem.getMap();
        int width = mapItem.getWidth();
        int height = mapItem.getHeight();

        height++;
        mapItem.setHeight(height);
        int[] temp = map;
        map = new int[map.length + width];
        System.arraycopy(temp, 0, map, 0, temp.length);
        mapItem.setMap(map);
        return true;
    }

    /**
     * 删除最后一行
     */
    public boolean rowDelete(MapItem mapItem) {
        int[] map = mapItem.getMap();
        int width = mapItem.getWidth();
        int height = mapItem.getHeight();

        if (map.length == 1) return false;
        //最后一行不是空,就不能删除
        for (int i = map.length - 1; i >= map.length - width; i--) {
            if (map[i] != ElementType.EMPTY.intValue) {
                return false;
            }
        }
        //能删除
        height--;
        mapItem.setHeight(height);
        int[] temp = map;
        map = new int[map.length - width];
        System.arraycopy(temp, 0, map, 0, map.length);
        mapItem.setMap(map);
        return true;
    }

    /**
     * 删除最后一列
     */
    public boolean colAdd(MapItem mapItem) {
        int[] map = mapItem.getMap();
        int width = mapItem.getWidth();
        int height = mapItem.getHeight();

        int[] temp = map;
        map = new int[map.length + height];
        int newI;
        //只对已有数据赋值,新增的单元格默认就是[0==EMPTY]
        for (int oldI = 0; oldI < temp.length; oldI++) {
            //偏移量=列数取整=oldI / width
            newI = oldI + oldI / width;
            map[newI] = temp[oldI];
        }
        width++;
        mapItem.setWidth(width);
        mapItem.setMap(map);
        return true;
    }

    /**
     * 删除最后一列
     */
    public boolean colDelete(MapItem mapItem) {
        int[] map = mapItem.getMap();
        int width = mapItem.getWidth();
        int height = mapItem.getHeight();

        log.debug("w={}, h={}, l={}", width, height, map.length);
        if (map.length == 1) return false;
        //最后一列不是空,就不能删除
        for (int i = map.length - 1; i >= 0; i -= width) {
            log.debug("i={}", i);
            if (map[i] != ElementType.EMPTY.intValue) {
                return false;
            }
        }
        int[] temp = map;
        map = new int[map.length - height];
        int oldI;
        width--;//赋值时,要先递减
        for (int newI = 0; newI < map.length; newI++) {
            //偏移量=列数取整=newI / width
            oldI = newI + newI / width;//和增加列时是一样的,只是index[是倒退的]
            map[newI] = temp[oldI];
        }
        mapItem.setWidth(width);
        mapItem.setMap(map);
        return true;
    }

}
